
#include<iostream>
#include<string>
using namespace std;

//场景: 模拟男士穿衣

class Boy		//抽象基类，代表男生 ,组件
{
public:
	virtual void wearClothes() = 0;
};


class ConcreteBoy : public Boy	//具体男生类， 具体组件
{
public:
	void wearClothes() override
	{
		cout << "首先穿上打底衫。" << endl;
	}
};


class Decorator : public Boy	//装饰器基类， 装饰器
{
protected:
	Boy* boy;

public:
	Decorator(Boy* b) : boy(b) {}

	virtual void wearClothes() override
	{
		if (boy != nullptr)
			boy->wearClothes();
	}

};


//接下来创建装饰器类:

//穿西服
class JacketDecorator : public Decorator    //具体装饰器
{
public:
	JacketDecorator(Boy* b) :Decorator(b) {}

	void wearClothes() override
	{
		Decorator::wearClothes();
		cout << "紧接着穿上西服。" << endl;
	}
};


//打领带
class TieDecorator : public Decorator   //具体装饰器
{
public:
	TieDecorator(Boy* b) :Decorator(b) {}

	void wearClothes() override
	{
		Decorator::wearClothes();
		cout << "最后再打领带。" << endl;
	}
};



int main()
{
	Boy* boy = new TieDecorator(new JacketDecorator(new ConcreteBoy()));

	boy->wearClothes();

	delete boy;

	return 0;
}
/*
首先穿上打底衫。
紧接着穿上西服。
最后再打领带。
*/










#include<iostream>
#include<memory>
#include<string>
using namespace std;

class component
{
public:
	virtual ~component() {};
	virtual string operation() const = 0;
};

class concreteComponent :public component
{
public:
	string operation() const override 
	{
		return "concreteComponent"; 
	}
};

class decorator :public component
{
protected:
	component* mComponent;
public:
	decorator(component* component) :mComponent(component) {}

	virtual ~decorator() {}

	string operation() const override
	{
		return mComponent->operation();
	}
};

class concreteDecoratorA : public decorator
{
public:
	concreteDecoratorA(component* component) :decorator(component) {}
	string operation() const override
	{
		return decorator::operation() + " concreteDecoratorA";
	}
};


class concreteDecoratorB : public decorator
{
public:
	concreteDecoratorB(component* component) :decorator(component) {}
	string operation() const override
	{
		return decorator::operation() + " concreteDecoratorB";
	}
};

void clientCode(shared_ptr<component> component)
{
	cout << component->operation() << endl;
}

int main()
{
	auto simple = shared_ptr<component>(new concreteComponent);
	cout << "========" << endl;
	clientCode(simple);
	cout << endl << endl;

	auto decorator1 =
		shared_ptr<component>(new concreteDecoratorA(simple.get()));

	auto decorator2 = 
		shared_ptr<component>(new concreteDecoratorB(decorator1.get()));

	clientCode(decorator2);
	return 0;
}


/*
========
concreteComponent


concreteComponent concreteDecoratorA concreteDecoratorB

*/